package net.mikoo.seals.biz.service.impl;

import java.util.Date;
import java.util.List;
import java.util.UUID;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import net.mikoo.seals.biz.common.helper.OrgsHelper;
import net.mikoo.seals.biz.mapper.OrganizationMapper;
import net.mikoo.seals.biz.mapper.OrganizationPartyMapper;
import net.mikoo.seals.biz.service.OrganizationService;
import net.mikoo.seals.common.exception.ParametersException;
import net.mikoo.seals.model.Organization;
import net.mikoo.seals.model.OrganizationParty;
import net.mikoo.seals.model.OrganizationPartyQuery;
import net.mikoo.seals.model.OrganizationQuery;

public class OrganizationServiceImpl implements OrganizationService {
	
	private Logger logger = LoggerFactory.getLogger(OrganizationServiceImpl.class);

	@Autowired
	private OrganizationMapper organizationMapper;
	
	@Autowired
	private OrganizationPartyMapper organizationPartyMapper;
	
	@Autowired
	private TransactionTemplate transactionTemplate;
	
	@Override
	public List<Organization> getTreeByQuery(OrganizationQuery query){
		
		
		if(query == null) {
			throw new ParametersException("query is null");
		}
		if(query.getCompanyId() == null) {
			throw new ParametersException("CompanyId is null");
		}
		List<Organization> orgs = organizationMapper.selectListByQuery(query);
		
		orgs = 	OrgsHelper.convertToTree(orgs, 0L, 0);
				
		return orgs;
	}

	
	@Override
	public void create(Organization organization) {

		if (organization == null) {
			throw new ParametersException("参数错误");
		}

		if (organization.getCompanyId() == null) {
			throw new ParametersException("所属公司不能为空");
		}

		if (StringUtils.isBlank(organization.getName())) {
			throw new ParametersException("机构名称不能为空");
		}

		if (organization.getParentId() == null) {
			organization.setParentId(0L);
			
		}
		
		String uuid = UUID.randomUUID().toString().replace("-", "").toLowerCase();
		organization.setOrganizationUid(uuid);
		if (organization.getParentId()==0L) {
			organization.setOrgsChain(uuid);
		} else {
			Organization orgs = organizationMapper.selectInfoById(organization.getParentId());
			organization.setOrgsChain(orgs.getOrgsChain() + "," + uuid);
		}

		organization.setCreateTime(new Date());
		organizationMapper.insert(organization);
	}
	
	@Override
	public Organization getInfoById(Long id) {
		if(id == null) {
			throw new ParametersException("参数错误");
		}
		return organizationMapper.selectInfoById(id);
	}
	
	@Override
	public void modify(Organization org) {
		if(org == null) {
			throw new ParametersException("org is null");
		}
		if(org.getOrganizationId() == null) {
			throw new ParametersException("organizationId is null");
		}
		
		if(org.getCompanyId() == null) {
			throw new ParametersException("CompanyId is null");
		}
		
//		if(StringUtils.isBlank(org.getName())) {
//			throw new ParametersException("机构名称不能为空");
//		}
		
		
		if (org.getParentId() !=null && org.getParentId() > 0 ) {
			Organization parent = organizationMapper.selectInfoById(org.getParentId());
			Organization exist = organizationMapper.selectInfoById(org.getOrganizationId());
			org.setOrgsChain(parent.getOrgsChain()+","+exist.getOrganizationUid());
		}
		
		organizationMapper.update(org);
	}
	

	@Override
	public List<OrganizationParty> getStaffList(OrganizationPartyQuery query) {
		if(query == null || query.getOrganizationId() == null || query.getCompanyId() == null) {
			throw new ParametersException("参数错误");
		}
		query.setOffset(0);
		query.setPageSize(10000);
		return organizationPartyMapper.selectByQueryToPage(query);
	}


	@Override
	public void removeStaff(OrganizationParty orgParty) {
		if(orgParty == null) {
			throw new ParametersException("orgParty is null");
		}
		
		if(orgParty.getCompanyId() == null) {
			throw new ParametersException("CompanyId is null");
		}
		if(orgParty.getPartyId() == null) {
			throw new ParametersException("PartyId is null");
		}
		if(orgParty.getOrganizationId() == null) {
			throw new ParametersException("PartyId is null");
		}
		
		organizationMapper.deleteParty(orgParty);
	}

	@Override
	public List<Organization> getListByQuery(OrganizationQuery query) {
		
		if(query == null) {
			throw new ParametersException("query is null");
		}
		List<Organization> orgs = organizationMapper.selectListByQuery(query);
		
		return orgs;
	}

	@Override
	public void deleteByQuery(OrganizationQuery query) {
		
		if(query == null) {
			throw new ParametersException("query is null");
		}
		
		List<Organization> orgs =  organizationMapper.selectListByQuery(query);
		for (Organization org : orgs) {
			List<Organization> subs = organizationMapper.selectListByParentId(org.getOrganizationId());
			if(subs != null && !subs.isEmpty()) {
				throw new ParametersException(org.getName()+"有子机构，请先删除子机构");
			}
		}
		
		this.transactionTemplate.execute(new TransactionCallbackWithoutResult() {
			
			@Override
			protected void doInTransactionWithoutResult(TransactionStatus status) {
				try {
					
					for (Organization org : orgs) {
						
						organizationMapper.deletePartyById(org.getOrganizationId());
					}
					
					Integer num = organizationMapper.deleteByQuery(query);
					if(num ==null || num == 0) {
						throw new ParametersException("删除失败");
					}
					
				}catch (ParametersException e) {
					status.setRollbackOnly();
					throw e;
				}catch (Exception e) {
					status.setRollbackOnly();
					throw e;
				}
				
				
			}
		});
		
	}


	@Override
	public void	addStaff(Long organizationId, List<Long> partyIds,Long companyId) {
		
		if(companyId == null) {
			throw new ParametersException("companyId is null");
		}
		
		if(organizationId == null) {
			throw new ParametersException("请选择机构");
		}
		
		if(partyIds == null || partyIds.isEmpty()) {
			
			throw new ParametersException("请选择人员");
		}
		
		transactionTemplate.execute(new TransactionCallbackWithoutResult() {

			@Override
			protected void doInTransactionWithoutResult(TransactionStatus status) {
				try {
					
//					OrganizationPartyQuery query = new OrganizationPartyQuery();
//					query.setCompanyId(companyId);
//					query.setPartyId(partyId);
					for (Long partyId : partyIds) {
						
						OrganizationParty ogrParty = new OrganizationParty();
						ogrParty.setCompanyId(companyId);
						ogrParty.setPartyId(partyId);
						ogrParty.setOrganizationId(organizationId);
						ogrParty.setCreateTime(new Date());
						organizationMapper.deleteParty(ogrParty);
						organizationMapper.insertParty(ogrParty);
					}
				} catch (Exception e) {
					status.setRollbackOnly();
					throw e;
				}
				
				
			}
			
		});
		
		
	}


	@Override
	public Integer getTotal(Long companyId) {
		Integer total = organizationMapper.countTotal(companyId);
		return total;
	}


	@Override
	public Organization getInfoByQuery(OrganizationQuery query) {
		
		Organization orgs = organizationMapper.selectInfoByQuery(query);
		
		return orgs;
	}
	
	
	@Override
	public Organization getInfoWithPartyByQuery(OrganizationQuery query) {
		
		Organization orgs = organizationMapper.selectInfoWithPartyByQuery(query);
		
		return orgs;
	}


	@Override
	public void createPart(OrganizationParty orgParty) {
		
		
		
		transactionTemplate.execute(new TransactionCallbackWithoutResult() {

			@Override
			protected void doInTransactionWithoutResult(TransactionStatus status) {
				try {
					organizationMapper.deleteParty(orgParty);
					organizationMapper.insertParty(orgParty);
				}catch (Exception e) {
					status.setRollbackOnly();
					logger.error("",e);
				}
				
			}
		});
		
		
	}


	@Override
	public Organization getInfoByPartyId(Long partyId) {
		Organization orgs = organizationMapper.selectInfoByPartyId(partyId);
		return orgs;
	}
}
